﻿
    using System;
    using System.Runtime.InteropServices;
namespace WCYCReader.Drawing
{
    public static class ImageTools
    {
        private const sbyte APP0 = -32;
        private const int BI_RGB = 0;
        private const int BI_RLE4 = 2;
        private const int BI_RLE8 = 1;
        public const int BMP_FORMAT = 1;
        private const sbyte EOI = -39;
        public const int GIF_FORMAT = 2;
        public const int JPG_FORMAT = 3;
        private const sbyte SOB = -1;
        private const sbyte SOF0 = -64;
        private const sbyte SOF1 = -63;
        private const sbyte SOF2 = -62;
        private const sbyte SOF3 = -61;
        private const sbyte SOF5 = -59;
        private const sbyte SOF6 = -58;
        private const sbyte SOF7 = -57;
        private const sbyte SOF9 = -55;
        private const sbyte SOFA = -54;
        private const sbyte SOFB = -53;
        private const sbyte SOFD = -51;
        private const sbyte SOFE = -50;
        private const sbyte SOFF = -49;
        private const sbyte SOI = -40;
        private const sbyte SOS = -38;
        public const int UNKNOW_FORMAT = 0x63;

        public static int[] getARGBfromBMP(sbyte[] imageData, Dimension maxDimension)
        {
            if (((maxDimension == null) || (maxDimension.width <= 0)) || (maxDimension.height <= 0))
            {
                return new int[0];
            }
            int num = ByteDataInputStream.readInt(imageData, 10, false);
            int num2 = ByteDataInputStream.readInt(imageData, 0x12, false);
            int num3 = ByteDataInputStream.readInt(imageData, 0x16, false);
            int num4 = ByteDataInputStream.readShort(imageData, 0x1a);
            int num5 = ByteDataInputStream.readShort(imageData, 0x1c);
            int num6 = ByteDataInputStream.readInt(imageData, 30, false);
            int num7 = ByteDataInputStream.readInt(imageData, 0x2e, false);
            int num8 = (num3 - 1) / maxDimension.height;
            int num9 = (num2 - 1) / maxDimension.width;
            int num10 = ((num9 < 0) || (num8 < 0)) ? 1 : ((num9 > num8) ? (num9 + 1) : (num8 + 1));
            maxDimension.width = ((num2 - 1) / num10) + 1;
            maxDimension.height = ((num3 - 1) / num10) + 1;
            if (num4 >= 2)
            {
                num4 -= 2;
            }
            else
            {
                num4 = -1;
            }
            if ((num7 == 0) && (num5 <= 8))
            {
                num7 = ((int) 1) << num5;
            }
            int[] numArray = null;
            if (num7 > 0)
            {
                numArray = new int[num7];
                for (int i = 0; i < num7; i++)
                {
                    int num12 = ByteDataInputStream.readInt(imageData, 0x36 + (i << 2), false) & 0xffffff;
                    if (i == num4)
                    {
                        numArray[i] = 0;
                    }
                    else
                    {
                        numArray[i] = num12 + -16777216;
                    }
                }
            }
            if (num6 == 0)
            {
                switch (num5)
                {
                    case 4:
                    {
                        int[] numArray3 = new int[maxDimension.width * maxDimension.height];
                        int num17 = ((num2 + 7) >> 1) & -4;
                        int num18 = num2 >> 1;
                        int[] numArray4 = new int[num2];
                        for (int j = 0; j < maxDimension.height; j++)
                        {
                            int num20 = num + ((num17 * ((maxDimension.height - 1) - j)) * num10);
                            for (int k = 0; k < num18; k++)
                            {
                                int num22 = imageData[num20++] & 0xff;
                                numArray4[k << 1] = numArray[num22 >> 4];
                                numArray4[(k << 1) + 1] = numArray[num22 & 15];
                            }
                            if ((num2 & 1) != 0)
                            {
                                numArray4[num2 - 1] = numArray[(imageData[num20] & 0xff) >> 4];
                            }
                            for (int m = 0; m < maxDimension.width; m++)
                            {
                                numArray3[m + (j * maxDimension.width)] = numArray4[m * num10];
                            }
                            num20 += num17 - num18;
                        }
                        return numArray3;
                    }
                    case 8:
                    {
                        int[] numArray2 = new int[maxDimension.width * maxDimension.height];
                        int num13 = (num2 + 3) & -4;
                        for (int n = 0; n < maxDimension.height; n++)
                        {
                            int num15 = num + ((num13 * ((maxDimension.height - 1) - n)) * num10);
                            for (int num16 = 0; num16 < maxDimension.width; num16++)
                            {
                                numArray2[num16 + (n * maxDimension.width)] = numArray[imageData[num15] & 0xff];
                                num15 += num10;
                            }
                        }
                        return numArray2;
                    }
                }
                goto Label_058B;
            }
            if ((num6 != 2) && (num6 != 1))
            {
                goto Label_058B;
            }
            int[] numArray5 = new int[maxDimension.width * maxDimension.height];
            int[] numArray6 = new int[num2];
            int num24 = 0;
            int num25 = num3 - 1;
            int index = num;
        Label_0398:
            while (imageData[index] != 0)
            {
                int num27 = imageData[index++] & 0xff;
                if (num6 == 1)
                {
                    int num28 = numArray[imageData[index++] & 0xff];
                    while (num27 > 0)
                    {
                        numArray6[num24++] = num28;
                        num27--;
                    }
                }
                else
                {
                    int num29 = imageData[index++] & 0xff;
                    int num30 = numArray[num29 >> 4];
                    int num31 = numArray[num29 & 15];
                    while (num27 > 1)
                    {
                        if (num24 < num2)
                        {
                            numArray6[num24++] = num30;
                        }
                        if (num24 < num2)
                        {
                            numArray6[num24++] = num31;
                        }
                        num27 -= 2;
                    }
                    if ((num27 == 1) && (num24 < num2))
                    {
                        numArray6[num24++] = num30;
                    }
                }
            }
            index++;
            switch (imageData[index])
            {
                case 0:
                    if ((num25 & (num10 - 1)) == 0)
                    {
                        int num32 = num25 / num10;
                        for (int num33 = 0; num33 < maxDimension.width; num33++)
                        {
                            numArray5[num33 + (num32 * maxDimension.width)] = numArray6[num33 * num10];
                        }
                    }
                    index++;
                    num24 = 0;
                    num25--;
                    if (num25 >= 0)
                    {
                        goto Label_0398;
                    }
                    return numArray5;

                case 1:
                    return numArray5;

                case 2:
                {
                    index++;
                    int num34 = imageData[index++] & 0xff;
                    int num35 = imageData[index++] & 0xff;
                    if (num35 < 0)
                    {
                        num35 = 0;
                    }
                    while (num35 > 0)
                    {
                        if ((num25 & (num10 - 1)) == 0)
                        {
                            int num36 = num25 / num10;
                            for (int num37 = 0; num37 < maxDimension.width; num37++)
                            {
                                numArray5[num37 + (num36 * maxDimension.width)] = numArray6[num37 * num10];
                                numArray6[num37 * num10] = 0;
                            }
                        }
                        num25--;
                        num35--;
                        if (num25 < 0)
                        {
                            return numArray5;
                        }
                    }
                    num24 += num34;
                    goto Label_0398;
                }
                default:
                {
                    int num38 = imageData[index++] & 0xff;
                    if (num6 == 1)
                    {
                        while (num38 > 0)
                        {
                            numArray6[num24++] = numArray[imageData[index++] & 0xff];
                            num38--;
                        }
                        break;
                    }
                    while (num38 > 1)
                    {
                        int num39 = imageData[index++] & 0xff;
                        if (num24 < num2)
                        {
                            numArray6[num24++] = numArray[num39 >> 4];
                        }
                        if (num24 < num2)
                        {
                            numArray6[num24++] = numArray[num39 & 15];
                        }
                        num38 -= 2;
                    }
                    if ((num38 == 1) && (num24 < num2))
                    {
                        numArray6[num24++] = numArray[(imageData[index++] & 0xff) >> 4];
                    }
                    break;
                }
            }
            if ((index & 1) != 0)
            {
                index++;
            }
            goto Label_0398;
        Label_058B:
            return null;
        }

        private static int getGIFBlockSize(sbyte[] gifData, int offset)
        {
            bool flag = false;
            int num = 0;
            while (!flag)
            {
                int num2 = gifData[offset + num] & 0xff;
                num += num2 + 1;
                if (num2 == 0)
                {
                    flag = true;
                }
            }
            return num;
        }

        public static int getImageInfo(sbyte[] imageData, out Dimension dimension)
        {
            dimension = new Dimension();
            int num = 0x63;
            if (imageData == null)
            {
                dimension.width = 0;
                dimension.height = 0;
                return num;
            }
            if (((imageData[0] == 0x47) && (imageData[1] == 0x49)) && (imageData[2] == 70))
            {
                ByteDataInputStream stream = new ByteDataInputStream(imageData, false);
                num = 2;
                try
                {
                    stream.readVoid(6);
                    dimension.width = stream.readShort();
                    dimension.height = stream.readShort();
                }
                catch (Exception)
                {
                    dimension.width = 0;
                    dimension.height = 0;
                }
                return num;
            }
            if ((imageData[0] == 0x42) && (imageData[1] == 0x4d))
            {
                ByteDataInputStream stream2 = new ByteDataInputStream(imageData, false);
                num = 1;
                try
                {
                    stream2.readVoid(10);
                    stream2.readInt();
                    stream2.readVoid(4);
                    dimension.width = stream2.readInt();
                    dimension.height = stream2.readInt();
                }
                catch (Exception)
                {
                    dimension.width = 0;
                    dimension.height = 0;
                }
                return num;
            }
            if (((imageData[0] == -1) && (imageData[1] == -40)) && ((imageData[2] == -1) && (((sbyte) (imageData[3] & 240)) == -32)))
            {
                ByteDataInputStream stream3 = new ByteDataInputStream(imageData, true);
                stream3.readVoid(4);
                dimension.width = 0;
                dimension.height = 0;
                num = 0x63;
                try
                {
                    int num2 = stream3.readShort() & 0xffff;
                    stream3.readVoid(num2 - 2);
                    while (stream3.readByte() == -1)
                    {
                        switch (stream3.readByte())
                        {
                            case -64:
                            case -63:
                            case -62:
                            case -61:
                            case -59:
                            case -58:
                            case -57:
                            case -55:
                            case -54:
                            case -53:
                            case -51:
                            case -50:
                            case -49:
                                stream3.readVoid(3);
                                dimension.height = stream3.readShort() & 0xffff;
                                dimension.width = stream3.readShort() & 0xffff;
                                stream3.readVoid(1);
                                return 3;

                            case -39:
                            case -38:
                                return num;
                        }
                        num2 = stream3.readShort() & 0xffff;
                        stream3.readVoid(num2 - 2);
                    }
                    return num;
                }
                catch (Exception)
                {
                    dimension.width = 0;
                    dimension.height = 0;
                    return num;
                }
            }
            num = 0x63;
            dimension.width = 0;
            dimension.height = 0;
            return num;
        }

        public static int removeApplicationExtensionBlockFromGIF(sbyte[] gifData)
        {
            int length = gifData.Length;
            try
            {
                if (((gifData[0] != 0x47) || (gifData[1] != 0x49)) || (gifData[2] != 70))
                {
                    return length;
                }
                int num2 = gifData[10] & 7;
                int num3 = ((int) 1) << (1 + num2);
                int index = 13 + (num3 * 3);
                for (sbyte i = gifData[index]; i == 0x21; i = gifData[index])
                {
                    sbyte num6 = gifData[index + 1];
                    index += 2;
                    if (num6 == -1)
                    {
                        int num7 = getGIFBlockSize(gifData, index);
                        Array.Copy(gifData, (int) (index + num7), gifData, (int) (index - 2), (int) (gifData.Length - (index + num7)));
                        length -= num7;
                        index -= 2;
                    }
                    else
                    {
                        index += getGIFBlockSize(gifData, index);
                    }
                }
            }
            catch (IndexOutOfRangeException)
            {
            }
            return length;
        }
    }
}

